import sys
parent_dir = "../pygl"
sys.path.append(parent_dir)
import OpenGL.GL as gl
import glm
import imgui
import numpy as np
from common.app_v1 import App
import pygl

class RectangleApp(App):
    # 初始化着色器，vao vbo等
    def setupVertex(self) -> None:
        self.program = pygl.ProgramVF("basic/shaders/rectangle.vs", 
                                      "basic/shaders/rectangle.fs")
        rect_width = 1.8
        rect_height = 1.8
        self.line_color = glm.vec3(1.0, 1.0, 1.0)
        vertices = [
            # position                                          # color
            glm.vec3(rect_width / 2.0, rect_height / 2.0, 0.0),  glm.vec3(0.0, 0.0, 1.0),
            glm.vec3(rect_width / 2.0, -rect_height / 2.0, 0.0), glm.vec3(0.0, 0.0, 1.0),
            glm.vec3(-rect_width / 2.0, -rect_height / 2.0, 0.0), glm.vec3(0.0, 0.0, 1.0),
            glm.vec3(-rect_width / 2.0, rect_height / 2.0, 0.0), glm.vec3(0.0, 0.0, 1.0)
        ]
        self.indices = np.array([
            0, 1, 3,
            1, 2, 3
        ], dtype=gl.GLuint)
        self.vao = pygl.VertexArrayObject()
        self.vbo = pygl.VertexBufferObject(np.array(vertices))
        self.ebo = pygl.ElementBufferObject(self.indices)
        binding_point = 0
        self.vao.setVertexBuffer(self.vbo, binding_point, 0, 
                                 6 * gl.sizeof(gl.GLfloat))
        self.vao.setElementBuffer(self.ebo)
        attribute_position = pygl.VertexAttribute("position", 0, 3, 
                                                  gl.GL_FLOAT, False, 0)
        attribute_color = pygl.VertexAttribute("color",1, 3, 
                        gl.GL_FLOAT, False, 3 * gl.sizeof(gl.GLfloat))
        self.vao.setVertexAttribute(binding_point, attribute_position)
        self.vao.setVertexAttribute(binding_point, attribute_color)
        self.wireframe = 0

    # 配置imgui界面元素
    def showImGui(self)->None:
        imgui.begin("设置")
        _, color = imgui.color_edit3("线框颜色", self.line_color.x, 
                    self.line_color.y, self.line_color.z)
        self.line_color = glm.vec3(color[0], color[1], color[2])
        if imgui.radio_button("实体模式", self.wireframe == 0):
            self.wireframe = 0
        if imgui.radio_button("线框模式", self.wireframe == 1):
            self.wireframe = 1
        if imgui.radio_button("实体加线框模式", self.wireframe == 2):
            self.wireframe = 2
        imgui.end()     

    # 渲染图形
    def render(self) -> None:
        gl.glClearNamedFramebufferfv(0, gl.GL_COLOR, 0, self.background_color.to_tuple())
        self.program.use()
        self.vao.bind()
        if self.wireframe == 0:
            self.renderMesh()
        elif self.wireframe == 1:
            self.renderWireframe()
        elif self.wireframe == 2:
            self.renderMeshWithWireframe()

    def renderMesh(self)->None:
        self.program.setUniform1i(1, 0)
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
        gl.glDrawElements(gl.GL_TRIANGLES, len(self.indices), gl.GL_UNSIGNED_INT, None)

    def renderWireframe(self)->None:
        self.program.setUniform3fv(0, self.line_color)
        self.program.setUniform1i(1, 1)
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
        gl.glLineWidth(5.0)
        gl.glDrawElements(gl.GL_TRIANGLES, len(self.indices), gl.GL_UNSIGNED_INT, None)
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
        gl.glLineWidth(1.0)

    def renderMeshWithWireframe(self)->None:
        gl.glEnable(gl.GL_POLYGON_OFFSET_LINE)
        gl.glPolygonOffset(1.0, 1.0)
        self.renderMesh()
        self.renderWireframe()
        gl.glDisable(gl.GL_POLYGON_OFFSET_LINE)

    # 释放资源
    def cleanup(self) -> None:
        self.vbo.delete()
        self.ebo.delete()
        self.vao.delete()
        self.program.delete()

if __name__ == "__main__":
    app = RectangleApp(100, 100, 800, 600, "你好，矩形App V1.0！")
    app.run()

